package com.kate.mall.bff.wx.service;

import cn.hutool.core.map.MapUtil;
import com.kate.mall.bff.wx.feign.ProductFeignClient;
import com.kate.mall.bff.wx.feign.SnmFeignClient;
import com.kate.mall.bff.wx.vo.BrandHomeVo;
import com.kate.mall.bff.wx.vo.goods.NewOrHotGoodsVo;
import com.kate.mall.bff.wx.vo.home.HomeCategoryVO;
import com.kate.mall.common.exception.NDException;
import com.kate.mall.common.utils.ListMap2ListVoUtils;
import com.kate.mall.common.utils.R;
import com.kate.mall.common.utils.ThreadPoolUtils;
import com.kate.mall.common.vo.messsage.MessageRowsVo;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.naming.Name;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author 新梦想.陈超
 * @version 2021.2
 * @Description: {TODO}
 * @date 2022/12/16 下午2:11
 */

@Service
public class HomeService {

    @Resource
    private ProductFeignClient GoodsFeignClient;

    @Resource
    private SnmFeignClient snmFeignClient;


//    @Cacheable( cacheNames= "服务名称",key ="业务名:表名:唯一标识" )
    /*
     unless :除了满足此条件外，其他情况都缓存
        #result：代表方法返回值对象    Spring SpEL表达式
     **/
    @Cacheable(cacheNames="bff-wx",key = "'h:i'",unless = "#result[data]?.size()==0")
    public R list() {
        Map resultMap = new HashMap();
        //TODO 1.新品列表   page=1  limit=6
        ThreadPoolExecutor pool = ThreadPoolUtils.instance(true);
        try {

            Future<R> newGoodsFuture = pool.submit(() -> {
                return GoodsFeignClient.queryNewOrHotGoodsList(generatorParams(
                        new String[]{"limit", "isNew", "sort", "order"},
                        new Object[]{"6", 1, "sort_order", "asc"}));
            });
            //TODO 2.优惠券列表 page=1  limit=4

            //TODO 3.分类列表 page=1  limit=10
            Future<R> categoryListFuture = pool.submit(() -> GoodsFeignClient.queryCategoryList(
                    generatorParams(new String[]{"limit", "sort", "order","parentId"},
                        new Object[]{"10","sort_order", "asc",0})));
            //TODO 4.团购专区列表 page=1  limit=3
            //TODO 5.轮播图列表  page=1  limit=5
            //TODO 6.品牌专区   page=1  limit=4
            Future<R> brandListFuture = pool.submit(() -> {
                return GoodsFeignClient.queryBrandList(generatorParams(new String[]{"limit", "sort", "order"},
                        new Object[]{"4","sort_order", "asc"}));
            });
            //TODO 7.热卖商品列表 page=1  limit=6

            Future<R> hotGoodsFuture = pool.submit(() -> {
                return GoodsFeignClient.queryNewOrHotGoodsList(generatorParams(new String[]{"limit", "isHot", "sort", "order"},
                        new Object[]{"6", 1, "sort_order", "asc"}));
            });

            //TODO 8.专题列表   page=1  limit=4
            //TODO 9.楼层商品列表 page=1  limit=4

            //TODO 10.查询模版消息
            Future<R> messageFuture = pool.submit(() -> {
                return snmFeignClient.refreshMessage();
            });



            parseFuture(newGoodsFuture, resultMap, "newGoodsList", NewOrHotGoodsVo.class);
            parseFuture(hotGoodsFuture, resultMap, "hotGoodsList", NewOrHotGoodsVo.class);
            parseFuture(brandListFuture, resultMap, "brandList", BrandHomeVo.class);
            parseFuture(categoryListFuture, resultMap, "channel", HomeCategoryVO.class);

            parseFutureMsg(messageFuture, resultMap, "messageRows", MessageRowsVo.class);
        } finally {
            pool.shutdown();
        }
        return R.ok().put("data", resultMap);
    }

    public void parseFutureMsg(Future<R> messageFuture, Map resultMap, String responseKey, Class<MessageRowsVo> voClazz) {
        R listR = null;
        try {
            listR = messageFuture.get();
        } catch (Exception e) {
            throw new NDException("首页消息请求数据异常....");
        }
        if (listR == null) return;
        MessageRowsVo messageRowsVo = null;
        try {
            messageRowsVo = voClazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        messageRowsVo.setLastRows((Integer) listR.get("lastRows"));
        messageRowsVo.setUnreadRows((Integer) listR.get("unreadRows"));
        resultMap.put(responseKey, messageRowsVo);
    }

    private void parseFuture(Future<R> future, Map resultMap, String responseKey, Class voClazz)  {
        R listR = null;
        try {
            listR = future.get();
        } catch (Exception e) {
            throw new NDException("首页接口请求数据异常....");
        }
        List<Map> newGoodsMapList = MapUtil.get(MapUtil.get(listR, "page", Map.class),
                "list", List.class);
        //裁剪字段两种方案：一、自己写工具类(框架)  二 、mapStruct框架
        //List<map>====>list<vo>
        List VoList = ListMap2ListVoUtils.entity2Vo(newGoodsMapList, voClazz);
        resultMap.put(responseKey, VoList);
    }

    public Map<String, Object> generatorParams(String[] keys, Object[] values) {
        ConcurrentHashMap<String, Object> params = MapUtil.newConcurrentHashMap();
        if (keys.length != values.length) {
            throw new RuntimeException("键值数量不匹配，参数错误");
        }
        for (int i = 0; i < keys.length; i++) {
            params.put(keys[i], values[i]);
        }
        return params;
    }
}
